import json
import time
from typing import Dict, List

import uvicorn
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Query, APIRouter
from fastapi.middleware.cors import CORSMiddleware

connections = APIRouter()


# 核心存储结构
service_connections: Dict[str, WebSocket] = {}  # 客服连接: {service_id: WebSocket}
user_connections: Dict[str, WebSocket] = {}  # 用户连接: {user_id: WebSocket}

user_bind_service: Dict[str, str] = {}  # 用户绑定的客服: {user_id: service_id}
service_users: Dict[str, List[str]] = {}  # 客服的用户列表: {service_id: [user_id列表]}


async def send_message(websocket: WebSocket, data: dict):
    """向指定连接发送JSON消息"""
    try:
        await websocket.send_text(json.dumps(data))
    except Exception as e:
        print(f"消息发送失败: {e}")


@connections.websocket("/ws/service/{service_id}")
async def service_websocket(websocket: WebSocket, service_id: str, name: str = Query("客服")):
    """客服连接端点"""
    await websocket.accept()
    service_connections[service_id] = websocket
    service_users.setdefault(service_id, [])  # 初始化用户列表
    print(f"客服 [{service_id}:{name}] 已上线")

    # 通知客服上线成功
    await send_message(websocket, {
        "type": "system",
        "message": f"客服 {service_id} 上线成功",
        "online_users": len(service_users[service_id])
    })

    try:
        while True:
            # 接收客服发送的消息
            data = await websocket.receive_text()
            msg = json.loads(data)

            # 只处理聊天消息
            to_user = msg["to_user"]
            content = msg["content"]

            # 发送消息给目标用户
            if to_user in user_connections:
                await send_message(user_connections[to_user], {
                    "type": "chat",
                    "from": "service",
                    "from_id": service_id,
                    "from_name": name,
                    "content": content,
                    "time": time.strftime("%H:%M:%S")
                })
                # 确认消息已发送
                # await send_message(websocket, {
                #     "type": "system",
                #     "message": f"消息已发送给用户 {to_user}"
                # })
            else:
                await send_message(websocket, {
                    "type": "error",
                    "message": f"用户 {to_user} 已离线"
                })

    except WebSocketDisconnect:
        # 清理客服连接
        if service_id in service_connections:
            del service_connections[service_id]
        print(f"客服 [{service_id}] 已下线")


@connections.websocket("/ws/user/{user_id}")
async def user_websocket(websocket: WebSocket, user_id: str, name: str = Query("用户"), service_id: str = Query(...)):
    """
    用户连接端点
    必须指定要绑定的客服ID（service_id为必填参数）
    """
    await websocket.accept()

    # 检查客服是否在线
    if service_id not in service_connections:
        await send_message(websocket, {
            "type": "error",
            "message": f"客服 {service_id} 不在线，请更换客服ID"
        })
        return

    # 绑定用户与客服关系
    user_connections[user_id] = websocket

    user_bind_service[user_id] = service_id
    service_users[service_id].append(user_id)  # 将用户加入客服的用户列表

    print(f"用户 [{user_id}:{name}] 已绑定客服 [{service_id}]")

    # 通知用户绑定成功
    await send_message(websocket, {
        "type": "system",
        "message": f"已成功连接客服 {service_id}",
        "service_id": service_id
    })

    # 通知客服有新用户加入
    await send_message(service_connections[service_id], {
        "type": "system",
        "message": f"新用户 [{user_id}:{name}] 已连接",
        "user_id": user_id,
        "user_name": name,
        "online_users": len(service_users[service_id])
    })

    try:
        while True:
            # 接收用户发送的消息
            data = await websocket.receive_text()
            msg = json.loads(data)

            # 只处理聊天消息
            if msg.get("type") == "chat" and "content" in msg:
                content = msg["content"]
                target_service = user_bind_service[user_id]

                # 发送消息给绑定的客服
                if target_service in service_connections:
                    await send_message(service_connections[target_service], {
                        "type": "chat",
                        "from": "user",
                        "from_id": user_id,
                        "from_name": name,
                        "content": content,
                        "time": time.strftime("%H:%M:%S")
                    })
                    # 确认消息已发送
                    # await send_message(websocket, {
                    #     "type": "system",
                    #     "message": "消息已发送给客服"
                    # })
                else:
                    await send_message(websocket, {
                        "type": "error",
                        "message": "客服已离线，无法发送消息"
                    })

    except WebSocketDisconnect:
        # 清理用户连接
        if user_id in user_connections:
            del user_connections[user_id]

        # 解除用户与客服的绑定
        if user_id in user_bind_service:
            bound_service = user_bind_service[user_id]
            del user_bind_service[user_id]

            # 从客服的用户列表中移除
            if bound_service in service_users and user_id in service_users[bound_service]:
                service_users[bound_service].remove(user_id)
                # 通知客服用户已离开
                if bound_service in service_connections:
                    await send_message(service_connections[bound_service], {
                        "type": "system",
                        "message": f"用户 [{user_id}] 已离开",
                        "online_users": len(service_users[bound_service])
                    })

        print(f"用户 [{user_id}] 已下线")


@connections.get("/online/services")
async def get_online_services():
    """获取当前在线的客服列表"""
    return {
        "online_services": list(service_connections.keys()),
        "count": len(service_connections)
    }


